package vip.xiaonuo.dev.modular.wechat.service.Impl;

import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import vip.xiaonuo.common.enums.CommonExceptionEnum;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.dev.modular.wechat.entity.DevWechat;
import vip.xiaonuo.dev.modular.wechat.mapper.DevWechatMapper;
import vip.xiaonuo.dev.modular.wechat.param.DevWechatParam;
import vip.xiaonuo.dev.modular.wechat.param.WechatCalendarParam;
import vip.xiaonuo.dev.modular.wechat.param.WechatConfigParam;
import vip.xiaonuo.dev.modular.wechat.param.wechatReq.WechatCreateCalendarParam;
import vip.xiaonuo.dev.modular.wechat.param.wechatReq.WechatCreateScheduleParam;
import vip.xiaonuo.dev.modular.wechat.param.wechatReq.WechatMemberCallbackParam;
import vip.xiaonuo.dev.modular.wechat.param.wechatReq.WechatMessageParam;
import vip.xiaonuo.dev.modular.wechat.param.wechatRes.WechatDepartmentRes;
import vip.xiaonuo.dev.modular.wechat.param.wechatRes.WechatUserRes;
import vip.xiaonuo.dev.modular.wechat.service.DevWechatService;
import vip.xiaonuo.dev.modular.wechat.util.DevWechatUtil;
import vip.xiaonuo.dev.modular.wechat.util.ase.AesException;
import vip.xiaonuo.dev.modular.wechat.util.ase.WXBizMsgCrypt;
import vip.xiaonuo.sys.api.SysOrgApi;
import vip.xiaonuo.sys.api.SysUserApi;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author xsl
 * @date 2024-06-18 12:00
 **/
@Slf4j
@Service
public class DevWechatServiceImpl extends ServiceImpl<DevWechatMapper, DevWechat> implements DevWechatService {

    @Resource
    SysOrgApi sysOrgApi;

    @Resource
    SysUserApi sysUserApi;

    @Override
    public void sendMsg(WechatMessageParam devWechatParam) {
        DevWechatUtil devWechatUtil = new DevWechatUtil();
        devWechatUtil.sendMsg(devWechatParam);
    }

    /**
     * 同步企业微信的机构消息
     *
     * @throws IOException
     */
    @Override
    public void syncWechatMember() throws IOException {
        DevWechatUtil devWechatUtil = new DevWechatUtil();
        devWechatUtil.getDepartment("1").forEach(item->{

        });
    }

    /**
     * 添加标签（创建活动使用）
     */
    @Override
    public void createTag(String tagName, String tagId) {
        DevWechatUtil devWechatUtil = new DevWechatUtil();
        devWechatUtil.createTag(tagName, tagId);
    }

    /**
     * 消息解密
     * @param sVerifyMsgSig
     * @param sVerifyTimeStamp
     * @param sVerifyNonce
     * @param sVerifyEchoStr
     * @return
     */
    @Override
    public String verifySign(String sVerifyMsgSig, String sVerifyTimeStamp, String sVerifyNonce, String sVerifyEchoStr) {
        WXBizMsgCrypt wxcpt  = DevWechatUtil.getVerifyClient();
        try {
            assert wxcpt != null;
            return wxcpt.VerifyURL(sVerifyMsgSig, sVerifyTimeStamp, sVerifyNonce, sVerifyEchoStr);
        }catch (AesException e){
            throw new CommonException(CommonExceptionEnum.ERROR417);
        }
    }

    /**
     * 加密处理
     * @param sReqMsgSig
     * @param sReqTimeStamp
     * @param sReqNonce
     * @param sReqData
     * @return
     */
    @Override
    public String deCodeSign(String sReqMsgSig, Integer sReqTimeStamp, String sReqNonce, String sReqData) {
        WXBizMsgCrypt wxcpt  = DevWechatUtil.getVerifyClient();
        try {
            String sMsg = wxcpt.DecryptMsg(sReqMsgSig, sReqTimeStamp.toString(), sReqNonce, sReqData);
            System.out.println("after decrypt msg: " + sMsg);
            // TODO: 解析出明文xml标签的内容进行处理
            // For example:2222222222222222222222222222222222222
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            StringReader sr = new StringReader(sMsg);
            InputSource is = new InputSource(sr);
            Document document = db.parse(is);

            Element root = document.getDocumentElement();
            NodeList nodelist1 = root.getElementsByTagName("Content");
            String content = nodelist1.item(0).getTextContent();
            System.out.println("Content：" + content);
            return content;

        } catch (Exception e) {
            // TODO
            // 解密失败，失败原因请查看异常
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 解密处理
     * @param sRespData
     * @param sReqTimeStamp
     * @param sReqNonce
     * @return
     */
    @Override
    public String enCodeSign(String sRespData, Integer sReqTimeStamp, String sReqNonce) {
        WXBizMsgCrypt wxcpt  = DevWechatUtil.getVerifyClient();
        try{
            String sEncryptMsg = wxcpt.EncryptMsg(sRespData, sReqTimeStamp.toString(), sReqNonce);
            System.out.println("after encrypt sEncrytMsg: " + sEncryptMsg);
            return sEncryptMsg;
        }
        catch(Exception e)
        {
            e.printStackTrace();
            // 加密失败
            return "";
        }
    }

    /**
     * 获取前度jsConfig
     * @param url
     * @return
     */
    @Override
    public WechatConfigParam getWechatJSConfig(String url) {
        DevWechatUtil devWechatUtil = new DevWechatUtil();
        return devWechatUtil.getJsConfig(url);
    }

    @Override
    public WXBizMsgCrypt getCodeClient() {
        return DevWechatUtil.getVerifyClient();
    }

    /**
     * 处理通信录回调信息处理逻辑
     * @param wechatMemberCallbackParam
     * @throws IOException
     */
    @Override
    public void callBackWechatMemberOrDepartment(WechatMemberCallbackParam wechatMemberCallbackParam) throws IOException {
        String changeType = wechatMemberCallbackParam.getChangeType();
        DevWechatUtil devWechatUtil = new DevWechatUtil();
        if(Objects.equals(changeType, "create_user")) {
            // 回调创建用户
            WechatDepartmentRes res = devWechatUtil.getDepartmentDetail(wechatMemberCallbackParam.getDepartment());
            sysUserApi.addUser(res.getDepartment().get("name"), wechatMemberCallbackParam.getName(), wechatMemberCallbackParam.getUserId(), wechatMemberCallbackParam.getAvatar(), wechatMemberCallbackParam.getMobile());
        }
        if(Objects.equals(changeType, "update_user")) {
            // 回调更新用户
            WechatDepartmentRes res = devWechatUtil.getDepartmentDetail(wechatMemberCallbackParam.getDepartment());
            sysUserApi.updateUser(res.getDepartment().get("name"), wechatMemberCallbackParam.getName(), wechatMemberCallbackParam.getUserId(), wechatMemberCallbackParam.getAvatar(), wechatMemberCallbackParam.getMobile(), wechatMemberCallbackParam.getNewUserId());
        }
        if(Objects.equals(changeType, "delete_user")) {
            // 回调删除用户
            sysUserApi.deleteUser(wechatMemberCallbackParam.getUserId());
        }

        if(Objects.equals(changeType, "create_party") && Objects.equals(wechatMemberCallbackParam.getParentId(), "1") ) sysOrgApi.createOrg(wechatMemberCallbackParam.getName(), wechatMemberCallbackParam.getId());

        if(Objects.equals(changeType, "update_party") && Objects.equals(wechatMemberCallbackParam.getParentId(), "1")) sysOrgApi.updateOrg(wechatMemberCallbackParam.getName(), wechatMemberCallbackParam.getId());
    }

    /**
     * 获取用户的登录信息
     * @param code
     * @return
     */
    @Override
    public JSONObject getUserId(String code) {
        DevWechatUtil devWechatUtil = new DevWechatUtil();
        String wechatID = devWechatUtil.getUserLoginDetail(code);
        // 查询用户ID
        return sysUserApi.getUserByWechatId(wechatID);
    }

    /**
     * 同步组织架构信息
     * @param orgId
     * @param departmentId
     * @return
     */
    @Override
    public WechatDepartmentRes getDepartmentIdList(String orgId, String departmentId) {
        DevWechatUtil devWechatUtil = new DevWechatUtil();
        List<Map<String, String>> list = devWechatUtil.getDepartment("819");
        // 遍历循环列表中的部门信息
        list.forEach(item->{
            // 根据部门创建结构
            WechatDepartmentRes res = devWechatUtil.getDepartmentDetail(item.get("id"));
            log.info("<----------------------------------获取的部门id为：{}, 部门名称为：{} ", item.get("id"), res.getDepartment().get("name"));
            if(Objects.equals(res.getDepartment().get("parentid"), "819")) sysOrgApi.createOrg(res.getDepartment().get("name"), item.get("id") );
        });
        return null;
    }

    /**
     * 获取部门员工信息
     * @param orgId
     * @return
     */
    @Override
    public List<String> getMemberInfo(String orgId) {
        DevWechatUtil devWechatUtil = new DevWechatUtil();
        List<String> res = new ArrayList<>();
        String wechatId = sysOrgApi.getWechatIdByOrgId(orgId);
        if(wechatId == null) throw new RuntimeException("组织机构未同步，请先同步机构信息");
        List<Map<String, String>> list = devWechatUtil.getUserInfo(wechatId);
        // 遍历循环列表中的部门信息
        list.forEach(item->{
            // 保存用户信息
            String userId = sysUserApi.addUserByWechat(item.get("userid"),item.get("name"), orgId );
            log.info("同步后新建用户信息为：{}", userId);
            res.add(userId);
        });
        return res;
    }

    /**
     * 创建日历，日程
     * @param wechatCalendarParam
     * @return
     */
    @Override
    public String createCalender(WechatCalendarParam wechatCalendarParam) {
        DevWechatUtil devWechatUtil = new DevWechatUtil();
        String id=null;
        if(wechatCalendarParam.getCalendarParam()!=null){
            WechatCreateCalendarParam wechatCreateCalendarParam = new WechatCreateCalendarParam();
            wechatCreateCalendarParam.setCalendar(wechatCalendarParam.getCalendarParam());
            id = devWechatUtil.addCalendar(wechatCreateCalendarParam);
        }
        if(wechatCalendarParam.getScheduleParam()!=null){
            WechatCreateScheduleParam wechatCreateScheduleParam = new WechatCreateScheduleParam();
            wechatCreateScheduleParam.setSchedule(wechatCalendarParam.getScheduleParam());
            devWechatUtil.addSchedule(wechatCreateScheduleParam);
        }
        return id;
    }

    @Override
    public String getUserIdByPhone(String phone) {
        DevWechatUtil devWechatUtil = new DevWechatUtil();
        return devWechatUtil.getUserId(phone);
    }

    @Override
    public String createSchedule(WechatCalendarParam wechatCalendarParam) {
        DevWechatUtil devWechatUtil = new DevWechatUtil();
        String id=null;
        if(wechatCalendarParam.getCalendarParam()!=null){
            WechatCreateCalendarParam wechatCreateCalendarParam = new WechatCreateCalendarParam();
            wechatCreateCalendarParam.setCalendar(wechatCalendarParam.getCalendarParam());
            id = devWechatUtil.addCalendar(wechatCreateCalendarParam);
        }
        if(wechatCalendarParam.getScheduleParam()!=null){
            WechatCreateScheduleParam wechatCreateScheduleParam = new WechatCreateScheduleParam();
            wechatCreateScheduleParam.setSchedule(wechatCalendarParam.getScheduleParam());
            devWechatUtil.addSchedule(wechatCreateScheduleParam);
        }
        return id;
    }
}
